package com.example.base.aop.login

import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.Observer
import org.aspectj.lang.annotation.Aspect
import org.aspectj.lang.annotation.Around
import org.aspectj.lang.ProceedingJoinPoint
import com.example.base.aop.login.LoginCallback
import com.example.base.aop.login.Login
import com.example.base.aop.login.LoginManager.gotoLoginPage
import com.example.base.aop.login.LoginManager.isLogin
import com.example.base.ui.view.broccoli.util.LogUtil
import com.jeremyliao.liveeventbus.LiveEventBus
import org.aspectj.lang.annotation.Pointcut
import org.aspectj.lang.reflect.MethodSignature
import java.lang.RuntimeException

@Aspect
class LoginAspect {
    @Pointcut("@annotation(com.example.base.aop.login.Login)")
    fun Login() {
    }

    @Pointcut("@annotation(com.example.base.aop.login.LoginCallback)")
    fun LoginCallback() {
    }

    //带回调的注解处理
    @Around("LoginCallback()")
    @Throws(Throwable::class)
    fun loginCallbackJoinPoint(joinPoint: ProceedingJoinPoint) {
        LogUtil.logE("走进AOP方法-LoginCallback()")
        val signature =
            joinPoint.signature as? MethodSignature ?: throw RuntimeException("该注解只能用于方法上")
        val loginCallback = signature.method.getAnnotation(
            LoginCallback::class.java) ?: return

        //判断当前是否已经登录
        if (isLogin()) {
            joinPoint.proceed()
        } else {
            val lifecycleOwner = joinPoint.target as LifecycleOwner
            LiveEventBus.get<Any>("login").observe(lifecycleOwner, object : Observer<Any?> {
                override fun onChanged(integer: Any?) {
                    try {
                        joinPoint.proceed()
                        LiveEventBus.get<Any>("login").removeObserver(this)
                    } catch (throwable: Throwable) {
                        throwable.printStackTrace()
                        LiveEventBus.get<Any>("login").removeObserver(this)
                    }
                }
            })
            gotoLoginPage()
        }
    }

    //不带回调的注解处理
    @Around("Login()")
    @Throws(Throwable::class)
    fun loginJoinPoint(joinPoint: ProceedingJoinPoint) {
        LogUtil.logE("走进AOP方法-Login()")
        val signature =
            joinPoint.signature as? MethodSignature ?: throw RuntimeException("该注解只能用于方法上")
        val login = signature.method.getAnnotation(
            Login::class.java) ?: return

        //判断当前是否已经登录
        if (isLogin()) {
            joinPoint.proceed()
        } else {
            //如果未登录，去登录页面
            gotoLoginPage()
        }
    }
}